#include <libs/klibc.h>
#include <drivers/kernel_logger.h>
#include <mm/mm.h>
#include <arch/arch.h>
#include <task/task.h>
// #include <arch/riscv64/mm/memmap.h>


__attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3);

__attribute__((used, section(".limine_requests_start"))) static volatile LIMINE_REQUESTS_START_MARKER;

__attribute__((used, section(".limine_requests_end"))) static volatile LIMINE_REQUESTS_END_MARKER;

// RTC 基地址（来自 FDT）
#define RTC_BASE 0x101000UL
#define RTC_SIZE 0x1000

// 寄存器偏移
#define RTC_TIME_LOW   0x00
#define RTC_TIME_HIGH  0x04

// 读取 64 位 RTC 时间戳
static inline uint64_t rtc_read_time(void) {
    volatile uint32_t *rtc = (volatile uint32_t *)RTC_BASE;

    uint32_t low, high1, high2;
    // 防止读取过程中高位进位，双读确认
    do {
        high1 = rtc[RTC_TIME_HIGH / 4];
        low   = rtc[RTC_TIME_LOW / 4];
        high2 = rtc[RTC_TIME_HIGH / 4];
    } while (high1 != high2);

    return ((uint64_t)high2 << 32) | low;
}

// 打印北京时间（简单时分秒）
static void print_time_beijing(uint64_t timestamp) {
    // 时间单位假定为秒；若为纳秒需除以 1e9
    if (timestamp > 1000000000000ULL) {
        timestamp /= 1000000000ULL; // 转为秒
    }

    // 转为 UTC+8
    timestamp += 8 * 3600;

    uint64_t total_seconds = timestamp % 86400; // 一天的秒数
    uint64_t hours   = total_seconds / 3600;
    uint64_t minutes = (total_seconds % 3600) / 60;
    uint64_t seconds = total_seconds % 60;

    printk("[RTC] Beijing Time %02lu:%02lu:%02lu\n",
           (unsigned long)hours,
           (unsigned long)minutes,
           (unsigned long)seconds);
}

void test_rtc(void) {
    // 1️⃣ 映射 RTC MMIO
    map_page_range(get_current_page_dir(),
                   RTC_BASE,
                   RTC_BASE,
                   RTC_SIZE,
                   PT_FLAG_R | PT_FLAG_W);

    // 2️⃣ 读取时间
    uint64_t now = rtc_read_time();

    // 3️⃣ 打印北京时间
    print_time_beijing(now);
}

void kmain(void)
{
    if (LIMINE_BASE_REVISION_SUPPORTED == false)
    {
        while (1)
        {
            arch_pause();
        }
    }
    arch_disable_interrupt();
    frame_init();

    map_page_range(
        get_current_page_dir(),
        0x10000000UL,
        0x10000000UL,
        0x1000, // 映射一整页
        PT_FLAG_R | PT_FLAG_W
    );

    *(volatile uint8_t *)(0x10000000UL) = 's';
    *(volatile uint8_t *)(0x10000000UL) = 'e';
    *(volatile uint8_t *)(0x10000000UL) = 'r';
    *(volatile uint8_t *)(0x10000000UL) = 'i';
    *(volatile uint8_t *)(0x10000000UL) = 'a';
    *(volatile uint8_t *)(0x10000000UL) = 'l';
    *(volatile uint8_t *)(0x10000000UL) = '_';
    *(volatile uint8_t *)(0x10000000UL) = 'o';
    *(volatile uint8_t *)(0x10000000UL) = 'k';
    *(volatile uint8_t *)(0x10000000UL) = '!';
    *(volatile uint8_t *)(0x10000000UL) = '\n';
    fdt_context_init_from_boot();
    init_serial();
    printk("init_serial_finished\n");
    test_rtc();

    // fdt_context_init_from_boot();

    printk("Naos-riscv starting...\n");
    
    heap_init();
    printk("heap_init_finished...\n");

    arch_early_init();
    printk("arch_earlyt_init_finished...\n");
    
    task_init();
    printk("task_init_finished...\n");

    arch_init();
    printk("arch_init_finished...\n");

    arch_enable_interrupt();


    // === 调试：每秒打印 kmain 状态 ===
    uint64_t last_print = get_timer();
    while (1)
    {   
        uint64_t now = get_timer();
        if (now - last_print >= TIMER_FREQ) { // 1 second
            printk("[kmain] CPU 0 (logical idle0) is running...\n");
            last_print = now;
        }
        arch_pause();
    }
}

